home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 28
/
Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso
/
Aminet
/
dev
/
c
/
dice-3.16.lha
/
examples
/
Printer_Driver
/
render.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-09-27
|
7KB
|
238 lines
/*
* RENDER.C
*
* David Berezowski - March/88.
* Modified for DICE - May/91 Matthew Dillon
*
* Copyright (c) 1988 Commodore-Amiga, Inc.
* (c)Copyright 1991 Matthew Dillon
*/
#include "defs.h"
Prototype __geta4 long Render(long, long, long, long);
#define NUMSTARTCMD 8 /* # of cmd bytes before binary data */
#define NUMENDCMD 1 /* # of cmd bytes after binary data */
#define NUMTOTALCMD (NUMSTARTCMD + NUMENDCMD) /* total of above */
#define NUMLFCMD 4 /* # of cmd bytes for linefeed */
#define MAXCOLORBUFS 4 /* max # of color buffers */
#define STARTLEN 16
#define PITCH 1
#define CONDENSED 2
#define LMARG 8
#define RMARG 11
#define DIREC 15
__geta4 long
Render(ct, x, y, status)
long ct, x, y, status;
{
static UWORD RowSize, ColorSize, BufSize, TotalBufSize;
static UWORD dataoffset, dpi_code;
static UWORD colors[MAXCOLORBUFS]; /* color ptrs */
static UWORD colorcodes[MAXCOLORBUFS]; /* printer color codes */
static UWORD NumColorBufs; /* actually number of color buffers req. */
/*
00-01 \003P set pitch (10 or 12 cpi)
02-02 \022 set condensed fine (on or off)
03-05 \033W\000 enlarge off
06-08 \033ln set left margin to n
09-11 \033Qn set right margin to n
12-12 \015 carriage return
13-15 \033U1 set uni-directional mode
*/
static UBYTE StartBuf[STARTLEN] =
"\033P\022\033W\000\033ln\033Qn\015\033U1";
UBYTE *ptr, *ptrstart, *ptr2, *ptr2start;
long i, err;
err = PDERR_NOERR;
switch(status) {
case 0: /* Master Initialization */
/*
* ct - pointer to IODRPReq structure.
* x - width of printed picture in pixels.
* y - height of printed picture in pixels.
*/
RowSize = x * 3;
ColorSize = RowSize + NUMTOTALCMD;
if (PD->pd_Preferences.PrintShade == SHADE_COLOR) {
NumColorBufs = MAXCOLORBUFS;
colors[0] = ColorSize * 3; /* Black */
colors[1] = ColorSize * 0; /* Yellow */
colors[2] = ColorSize * 1; /* Magenta */
colors[3] = ColorSize * 2; /* Cyan */
colorcodes[0] = 4; /* Yellow */
colorcodes[1] = 1; /* Magenta */
colorcodes[2] = 2; /* Cyan */
colorcodes[3] = 0; /* Black */
} else { /* grey-scale or black&white */
NumColorBufs = 1;
colors[0] = ColorSize * 0; /* Black */
colorcodes[0] = 0; /* Black */
}
BufSize = ColorSize * NumColorBufs + NUMLFCMD;
TotalBufSize = BufSize * 2;
PD->pd_PrintBuf = AllocMem(TotalBufSize, MEMF_PUBLIC);
if (PD->pd_PrintBuf == NULL)
err = PDERR_BUFFERMEMORY;
else {
dataoffset = NUMSTARTCMD;
/*
* This printer prints graphics within its
* text margins. This code makes sure the
* printer is in 10 cpi and then sets the
* left and right margins to their minimum
* and maximum values (respectively). A
* carriage return is sent so that the
* print head is at the leftmost position
* as this printer starts printing from
* the print head's position. The printer
* is put into unidirectional mode to
* reduce wavy vertical lines.
*/
StartBuf[PITCH] = 'P'; /* 10 cpi */
StartBuf[CONDENSED] = '\022'; /* off */
/* left margin of 1 */
StartBuf[LMARG] = 0;
/* right margin of 80 or 136 */
StartBuf[RMARG] = PD->pd_Preferences.
PaperSize == W_TRACTOR ? 136 : 80;
/* uni-directional mode */
StartBuf[DIREC] = '1';
err = (*(PD->pd_PWrite))(StartBuf, STARTLEN);
}
break;
case 1: /* Scale, Dither and Render */
/*
* ct - pointer to PrtInfo structure.
* x - 0.
* y - row # (0 to Height - 1).
*/
Transfer((void *)ct, y, &PD->pd_PrintBuf[dataoffset], colors);
break;
case 2: /* Dump Buffer to Printer */
/*
* ct - 0.
* x - 0.
* y - # of rows sent (1 to NumRows).
*/
/* white-space strip */
ptrstart = &PD->pd_PrintBuf[dataoffset];
ptr2start = ptr2 = ptrstart - NUMSTARTCMD;
x = 0; /* flag no transfer required yet */
for (ct=0; ct<NumColorBufs; ct++, ptrstart += ColorSize) {
i = RowSize;
ptr = ptrstart + i - 1;
while (i > 0 && *ptr == 0) {
i--;
ptr--;
}
if (i != 0) { /* if data */
/* convert to # of pixels */
i = (i + 2) / 3;
ptr = ptrstart - NUMSTARTCMD;
*ptr++ = 27;
*ptr++ = 'r';
*ptr++ = colorcodes[ct]; /* color */
*ptr++ = 27;
*ptr++ = '*';
*ptr++ = dpi_code; /* density */
*ptr++ = i & 0xff;
*ptr++ = i >> 8; /* size */
i *= 3; /* back to # of bytes used */
*(ptrstart + i) = 13; /* cr */
i += NUMTOTALCMD;
/* if must transfer data */
if (x != 0) {
/* get src start */
ptr = ptrstart - NUMSTARTCMD;
/* xfer and update dest ptr */
do {
*ptr2++ = *ptr++;
} while (--i);
}
else { /* no transfer required */
/* update dest ptr */
ptr2 += i;
}
}
/* if compacted or 0 */
if (i != RowSize + NUMTOTALCMD) {
/* we need to transfer next time */
x = 1;
}
}
*ptr2++ = 13; /* cr */
*ptr2++ = 27;
*ptr2++ = 'J';
*ptr2++ = y; /* y/180 lf */
err = (*(PD->pd_PWrite))(ptr2start, ptr2 - ptr2start);
if (err == PDERR_NOERR) {
dataoffset = (dataoffset == NUMSTARTCMD ?
BufSize : 0) + NUMSTARTCMD;
}
break;
case 3: /* Clear and Init Buffer */
/*
* ct - 0.
* x - 0.
* y - 0.
*/
ptr = &PD->pd_PrintBuf[dataoffset];
i = BufSize - NUMTOTALCMD - NUMLFCMD;
do {
*ptr++ = 0;
} while (--i);
break;
case 4: /* Close Down */
/*
* ct - error code.
* x - io_Special flag from IODRPReq.
* y - 0.
*/
/* if user did not cancel print */
if (ct != PDERR_CANCEL) {
/* restore preferences pitch and margins */
if (PD->pd_Preferences.PrintPitch == ELITE) {
StartBuf[PITCH] = 'M'; /* 12 cpi */
} else if (PD->pd_Preferences.PrintPitch == FINE) {
StartBuf[CONDENSED] = '\017'; /* on */
}
StartBuf[LMARG] = PD->pd_Preferences.PrintLeftMargin - 1;
StartBuf[RMARG] = PD->pd_Preferences.PrintRightMargin;
StartBuf[DIREC] = '0'; /* bi-directional */
err = (*(PD->pd_PWrite))(StartBuf, STARTLEN);
}
/* wait for both buffers to empty */
(*(PD->pd_PBothReady))();
if (PD->pd_PrintBuf != NULL)
FreeMem(PD->pd_PrintBuf, TotalBufSize);
break;
case 5: /* Pre-Master Initialization */
/*
* ct - 0 or pointer to IODRPReq structure.
* x - io_Special flag from IODRPReq.
* y - 0.
*
* Kludge for weak power supplies.
* FANFOLD - use all 24 pins (default).
* SINGLE - use only 16 pins.
*/
PED->ped_NumRows = ((PD->pd_Preferences.PaperType == SINGLE) ? 16 : 24);
dpi_code = SetDensity(x & SPECIAL_DENSITYMASK);
break;
}
return(err);
}